package com.msgqu.share.config;

import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SentinelServersConfig;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.List;
import java.util.Objects;

/**
 * @description:
 * @author: wsj
 * @create: 2020-11-14 20:59
 * @throws:
 */
@Configuration
public class RedisConfig{

    @Autowired
    private RedisProperties redisProperties;
    @Value("${spring.redis.redisson.database}")
    private int redissonDatabase;
    @Value("${spring.redis.redisson.poolsize}")
    private int redissPoolsize;
    private static final String REDIS_PROTOCOL = "redis://";
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        // 设置值（value）的序列化采用Jackson2JsonRedisSerializer。
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // 设置键（key）的序列化采用StringRedisSerializer。
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }


    @Bean
    public RedissonClient redissonClient() {
        Config config = new Config();
        RedisProperties.Sentinel sentinel = redisProperties.getSentinel();
        RedisProperties.Cluster cluster = redisProperties.getCluster();
        if(!Objects.isNull(sentinel)){
            //设置哨兵模式分布式锁
            setRedissonSentinelConfig(config);
        }else if(!Objects.isNull(cluster)){
            //设置集群分布式锁
        }else{
            //单节点redis分布式锁
            setRedissonSingleConfig(config);
        }
        return Redisson.create(config);
    }

    private void setRedissonSentinelConfig(Config config) {
        List<String> nodes = redisProperties.getSentinel().getNodes();
        String[] newNodes = new String[nodes.size()];
        for(int i= 0; i < nodes.size(); i++){
            newNodes[i] = nodes.get(i).startsWith(REDIS_PROTOCOL)?nodes.get(i):REDIS_PROTOCOL.concat(nodes.get(i));
        }
        SentinelServersConfig serverConfig = config.useSentinelServers()
                .addSentinelAddress(newNodes)
                .setMasterName(redisProperties.getSentinel().getMaster())
                .setDatabase(redissonDatabase)
                .setTimeout(((Long)redisProperties.getTimeout().getSeconds()).intValue() * 1000)
                .setMasterConnectionPoolSize(redissPoolsize)
                .setSlaveConnectionPoolSize(redissPoolsize);
        if (StringUtils.isNotBlank(redisProperties.getPassword())) {
            serverConfig.setPassword(redisProperties.getPassword());
        }
    }
    /**
     * @description: 设置redisson单机模式配置
     * @params: [config]
     * @return: void
     * @author: wsj
     * @create: 2020-11-15 12:55
     * @throws
     */
    private void setRedissonSingleConfig(Config config){
        String host = redisProperties.getHost();
        int port = redisProperties.getPort();
        Duration duration = redisProperties.getTimeout();
        Long seconds = duration.getSeconds();
        RedisProperties.Pool pool = redisProperties.getJedis().getPool();
        SingleServerConfig serverConfig = config.useSingleServer()
                .setAddress(REDIS_PROTOCOL.concat(host).concat(":").concat(String.valueOf(port)))
                .setDatabase(redissonDatabase)
                .setTimeout(seconds.intValue()*1000)
                .setConnectionMinimumIdleSize(pool.getMinIdle())
                .setConnectionPoolSize(redissPoolsize)
                .setPassword(redisProperties.getPassword());
        if (StringUtils.isNotBlank(redisProperties.getPassword())) {
            serverConfig.setPassword(redisProperties.getPassword());
        }
    }




}
